home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 001-025 / scopedisk12 / pspool1.0 / print.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  20KB  |  576 lines

  1.  
  2. /* Print.c    V1.0.0    27-Mar-88    ) Frangois Gagnon */
  3.  
  4. /*
  5.    Copyright ) 1988  Frangois Gagnon,  All Rights Reserved.
  6.  
  7.    The author does not make any warranty expressed or implied,
  8.    or assumes any liability or responsiblity for the use of
  9.    this software.
  10.  
  11.    Permission is hereby granted to copy, reproduce, redistribute
  12.    or otherwise use this software as long as it is for non-profit.
  13.    This notice and the above copyright notice must remain intact
  14.    and appear on all copies.
  15.  
  16.    Permission is also granted to correct any problems with this
  17.    software, but modifications and improvements are reserved by
  18.    the author.
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <ctype.h>
  23. #include <time.h>
  24.  
  25. #include <exec/memory.h>
  26. #include <exec/ports.h>
  27. #include <exec/nodes.h>
  28. #include <intuition/preferences.h>
  29. #include <libraries/dos.h>
  30. #include <libraries/dosextens.h>
  31.  
  32. #include "stdefs.h"
  33. #include "Print_Spool.h"
  34.  
  35. /* Declarations of status messages */
  36. local   char    FIND[] = "\nPrint: Unable to find Spool port.\n\n";
  37. local   char    PROT[] = "\nPrint: Mismatched protocol versions.\n\n";
  38. local   char    PORT[] = "\nPrint: Unable to create Print port.\n\n";
  39. local   char    DATA[] = "\nPrint: Unable to allocate memory.\n\n";
  40. local   char    EXEC[] = "\nPrint: Unknown or ambiguous command = %s.\n\n";
  41. local   char    LOCK[] = "\nPrint: File not found = %s.\n\n";
  42. local   char    TYPE[] = "\nPrint: Wrong file type = %s.\n\n";
  43. local   char    SIZE[] = "\nPrint: File name too long = %s%s.\n\n";
  44.  
  45. /* Definition for Execution */
  46. local   struct  Inform          *Print_Data;
  47. local   struct  MsgPort         *Spool_Port, *Print_Port;
  48. local   struct  FileInfoBlock   *Print_Info;
  49.  
  50. local   File    *Print_List = NULL, *Print_Last = NULL;
  51. local   int      Print_File = PS_Insert;
  52. local   int      Print_Opts = (Opts_Headers | Opts_Numbers);
  53. local   int      Print_Flag = 0;
  54. local   int      Print_Copy = 1;
  55.  
  56. #define Options( Mask, Opts) (Print_Opts = (Print_Opts & ~Mask) + Opts)
  57.  
  58. /*****************************/
  59. /* Define Available Commands */
  60. /*****************************/
  61.  
  62. /* Add option commands */
  63. #define PS_CPI10        30
  64. #define PS_CPI12        31
  65. #define PS_CPI17        32
  66. #define PS_LPI6         33
  67. #define PS_LPI8         34
  68. #define PS_NARROW       35
  69. #define PS_WIDE         36
  70. #define PS_SHORT        37
  71. #define PS_LONG         38
  72.  
  73. #define PS_HEADER       40
  74. #define PS_NUMBER       41
  75. #define PS_KEEP         42
  76. #define PS_DELETE       43
  77. #define PS_DRAFT        44
  78. #define PS_LETTER       45
  79.  
  80. /* Define the data structure */
  81. #define Print_Size      26
  82. #define Print_Used       7
  83. struct  Print_Type      { char Name[Print_Used];
  84.                           byte Code;
  85.                         };
  86.  
  87. local   struct  Print_Type      Print_Exec[Print_Size] = {
  88.   { "CANCEL", PS_Cancel }, { "CHANGE", PS_Change }, { "CPI10",  PS_CPI10  },
  89.   { "CPI12",  PS_CPI12  }, { "CPI17",  PS_CPI17  }, { "DELETE", PS_DELETE },
  90.   { "DRAFT",  PS_DRAFT  }, { "FINISH", PS_Finish }, { "FREEZE", PS_Freeze },
  91.   { "HEADER", PS_HEADER }, { "INSERT", PS_Insert }, { "KEEP",   PS_KEEP   },
  92.   { "LETTER", PS_LETTER }, { "LONG",   PS_LONG   }, { "LPI6",   PS_LPI6   },
  93.   { "LPI8",   PS_LPI8   }, { "NARROW", PS_NARROW }, { "NUMBER", PS_NUMBER },
  94.   { "REMOVE", PS_Remove }, { "REPORT", PS_Report }, { "RESET",  PS_Resets },
  95.   { "RESUME", PS_Resume }, { "RETURN", PS_Return }, { "SHORT",  PS_SHORT  },
  96.   { "UPDATE", PS_Update }, { "WIDE",   PS_WIDE   }};
  97.  
  98. /********************************/
  99. /* Search Allowing Abbreviatoin */
  100. /********************************/
  101.  
  102. local   int     Find_Command( Name)
  103. /*********************************/
  104. register char   Name[];
  105.  
  106. { register int  Length, Result;
  107.   auto     int  Test,   Next;
  108.   extern   int  strncmp();
  109.  
  110.   for (Length = 0; Name[Length] != NUL; ++Length)
  111.     Name[Length] = toupper( Name[Length]);
  112.  
  113.   Next = 1; Result = -1;
  114.   do /* The name table must be sorted */
  115.   { Test = Next;
  116.     if (++Result == Print_Size) { Next = -1; break; }
  117.     Next = strncmp( Name, Print_Exec[Result].Name, Length);
  118.   }
  119.   while (Test > 0);
  120.  
  121.   if ((Test != 0) || (Next == 0)) return 0;
  122.   return Print_Exec[Result - 1].Code;
  123. }
  124.  
  125. /******************************/
  126. /* Initialization of Defaults */
  127. /******************************/
  128.  
  129. #define INTUITIONNAME           "intuition.library"
  130. public  struct IntuitionBase    *IntuitionBase;
  131.  
  132. local   void    Default_Values()
  133. /******************************/
  134.  
  135. { auto   struct Preferences     PrefBuffer;
  136.   auto   int                    Temp;
  137.   extern struct IntuitionBase  *OpenLibrary();
  138.   extern struct Preferences    *GetPrefs();
  139.  
  140.   /* Fetch the information from the system */
  141.   IntuitionBase = OpenLibrary( INTUITIONNAME, 0L);
  142.   if (IntuitionBase == NULL) return;
  143.   GetPrefs( &PrefBuffer, (long) sizeof( struct Preferences));
  144.   CloseLibrary( IntuitionBase);
  145.  
  146.   /* Extract the information from the structure */
  147.   if      (PrefBuffer.PrintPitch == ELITE) Print_Opts |= Line_12;
  148.   else if (PrefBuffer.PrintPitch == FINE)  Print_Opts |= Line_17;
  149.  
  150.   Temp = (PrefBuffer.PrintSpacing == EIGHT_LPI ? 8 : 6);
  151.   if (PrefBuffer.PrintQuality == LETTER)    Print_Flag |= Flag_Quality;
  152.   if (PrefBuffer.PrintSpacing == EIGHT_LPI) Print_Opts |= Page_8;
  153.   if (PrefBuffer.PaperSize    == W_TRACTOR) Print_Opts |= Line_13;
  154.   if (PrefBuffer.PaperLength / Temp == 11)  Print_Opts |= Page_11;
  155. }
  156.  
  157.  
  158. /****************************/
  159. /* Printing Utility Routine */
  160. /****************************/
  161.  
  162. local   char    Value[3][3] = { "10", "12", "17" };
  163.  
  164. local   void    Show_File( Info_File)
  165. /***********************************/
  166. register File   *Info_File;
  167.  
  168. { printf( "%3s%4s%4s%4s%3c%c%c%c%6d %6ld  %s\n",
  169.         Value[Info_File->File_Opts & Line_Density],
  170.         (Info_File->File_Opts & Line_Formats ? "13" :   "8"),
  171.         (Info_File->File_Opts & Page_Density ?  "8" :   "6"),
  172.         (Info_File->File_Opts & Page_Formats ? "11" : "8.5"),
  173.         (Info_File->File_Opts & Opts_Headers ?  'T' :   'F'),
  174.         (Info_File->File_Opts & Opts_Numbers ?  'T' :   'F'),
  175.         (Info_File->File_Flag & Flag_Quality ?  'L' :   'D'),
  176.         (Info_File->File_Flag & Flag_Deleted ?  'D' :   'K'),
  177.         Info_File->File_Copy, Info_File->File_Size, Info_File->File_Name);
  178. }
  179.  
  180. /*********************************/
  181. /* General Communication Routine */
  182. /*********************************/
  183.  
  184. local   int     Request_Action( Action)
  185. /*************************************/
  186. int     Action;
  187.  
  188. { extern struct MsgPort *FindPort();
  189.   extern struct Inform  *GetMsg();
  190.  
  191.   /* Prepare the message for sending */
  192.   Print_Data->Packet.mn_Node.ln_Type = NT_MESSAGE;
  193.   Print_Data->Packet.mn_ReplyPort    = Print_Port;
  194.   Print_Data->Number                 = PROTOCOL;
  195.   Print_Data->Action                 = Action;
  196.  
  197.   /* Send the request message across  */
  198.   /* Making sure the port still exist */
  199.   Forbid();
  200.   if ((Spool_Port = FindPort( SPOOLNAME)) == NULL)
  201.   { Permit(); fprintf( stderr, FIND); return TRUE; }
  202.   PutMsg( Spool_Port, Print_Data);
  203.   Permit();
  204.  
  205.   /* Receive the result message */
  206.   do    WaitPort( Print_Port);
  207.   while ((Print_Data = GetMsg( Print_Port)) == NULL);
  208.  
  209.   /* Check the protocol version */
  210.   if (Print_Data->Number != PROTOCOL)
  211.   { fprintf( stderr, PROT); return TRUE; }
  212.   return FALSE;
  213. }
  214.  
  215. /*************************************/
  216. /* Request the status of the Spooler */
  217. /*************************************/
  218.  
  219. local   char    *State[] =
  220.         { "\nSpool: Waiting for a file to print.\n",
  221.           "\nSpool: Waiting for a change of paper.\n",
  222.           "\nSpool: Waiting to access the printer.\n",
  223.           "\nSpool: Printing a requested file.\n",
  224.           "\nSpool: Printing but will pause after the file.\n",
  225.           "\nSpool: Pausing between two files.\n",
  226.           "\nSpool: Pausing in the middle of a file.\n"
  227.         };
  228.  
  229. local   void    Request_Report()
  230. /******************************/
  231.  
  232. { register File *File_List, *File_Next;
  233.   register byte  Prog_Info;
  234.  
  235.   /* Request the wanted operation */
  236.   if (Request_Action( PS_Report)) return;
  237.  
  238.   /* Display the status information */
  239.   printf( State[Prog_Info = Print_Data->Detail.Status.Prog_State]);
  240.   if (Print_Data->Detail.Status.Flag_State)
  241.     printf( "Spool: Set to terminate its execution.\n");
  242.   if (Print_Data->Detail.Status.Opts_State & Flag_Partial)
  243.     printf( "Spool: Partial list of files, unable to allocate memory.\n");
  244.   if ((Prog_Info == Exec_State) || (Prog_Info == File_State) ||
  245.       (Prog_Info == Stop_State) )
  246.   { printf( "Spool: Printing %ld chars ... %ld lines ... %ld pages.\n",
  247.             Print_Data->Detail.Status.Char_Print,
  248.             Print_Data->Detail.Status.Line_Print,
  249.             Print_Data->Detail.Status.Page_Print);
  250.   }
  251.  
  252.   /* Display the contents of the print queue */
  253.   if ((File_List = Print_Data->Detail.Status.File_Print) != NULL)
  254.   { printf( "\ncpi ipl lpi ipp  hnqd  copy   size  report\n");
  255.     do
  256.     { File_List = (File_Next = File_List)->File_Next;
  257.       Show_File( File_Next);
  258.       FreeMem( File_Next, (long) sizeof( File));
  259.     }
  260.     while (File_List != NULL);
  261.   }
  262.   putchar( '\n');
  263. }
  264.  
  265. /*************************************/
  266. /* Request the removal of some files */
  267. /*************************************/
  268.  
  269. local   void    Request_Remove( Name)
  270. /***********************************/
  271. char    Name[];
  272.  
  273. { register File *Temp_File, *Temp_Next;
  274.   strncpy( Print_Data->Detail.Remove, Name, Name_Size);
  275.   if (Request_Action( PS_Remove)) return;
  276.  
  277.   if ((Temp_File = Print_Data->Detail.Insert) != NULL)
  278.   { printf( "\ncpi ipl lpi ipp  hnqd  copy   size  remove\n");
  279.     do
  280.     { Temp_File = (Temp_Next = Temp_File)->File_Next;
  281.       Show_File( Temp_Next);
  282.       FreeMem( Temp_Next, (long) sizeof( File));
  283.     }
  284.     while (Temp_File != NULL);
  285.   }
  286.   putchar( '\n');
  287. }
  288.  
  289. /**************************************/
  290. /* Perform the specified file request */
  291. /**************************************/
  292.  
  293. local   void    Perform()
  294. /***********************/
  295.  
  296. { if (Print_List != NULL)
  297.   { /* Execute the operation */
  298.     if (Print_File == PS_Insert) Print_Data->Detail.Insert = Print_List;
  299.     if (Print_File == PS_Update) Print_Data->Detail.Update = Print_List;
  300.     Print_Last->File_Next = NULL;
  301.     if (Request_Action( Print_File))
  302.     { do
  303.       { Print_List = (Print_Last = Print_List)->File_Next;
  304.         FreeMem( Print_Last, (long) sizeof( File));
  305.       }
  306.       while (Print_List != NULL);
  307.       return;
  308.     }
  309.  
  310.     if (Print_File == PS_Insert) Print_List = NULL;
  311.     if (Print_File == PS_Update)
  312.     { printf( "\ndone   cpi ipl lpi ipp  hnqd  copy   size  update\n");
  313.       do
  314.       { Print_List = (Print_Last = Print_List)->File_Next;
  315.         printf( "%s",
  316.           (Print_Last->File_Flag & Flag_Updated ?  "TRUE   " : "FALSE  "));
  317.         Show_File( Print_Last);
  318.         FreeMem( Print_Last, (long) sizeof( File));
  319.       }
  320.       while (Print_List != NULL);
  321.       putchar( '\n');
  322. } } }
  323.  
  324. /*********************************/
  325. /* File Search Utililty Routines */
  326. /*********************************/
  327.  
  328. local    int    File_Match( Name, Data)
  329. /*************************************/
  330. register char   *Name, *Data;
  331.  
  332. { auto     char *Save_Name[10],
  333.                 *Save_Data[10];
  334.   register int   Save;
  335.  
  336.   if ((*Data == NUL) || (*Name == NUL)) return FALSE;
  337.   Save = -1;
  338.  
  339.   while ((*Data != NUL) || (*Name != NUL))
  340.   { if (*Data == '*')
  341.     { if (*++Data == NUL) return TRUE;
  342.       if ( ++Save ==  10) return FALSE;
  343.       Save_Name[Save] = Name;
  344.       Save_Data[Save] = Data;
  345.       continue;
  346.     }
  347.     if (   ((*Data == '?') && (*Name != NUL))
  348.         || (toupper(*Data) == toupper(*Name)))
  349.     { ++Data; ++Name; continue; }
  350.  
  351.     if (*Name == NUL) --Save;
  352.     if ( Save <    0) return FALSE;
  353.     Name = ++Save_Name[Save];
  354.     Data =   Save_Data[Save];
  355.   }
  356.   return TRUE;
  357. }
  358.  
  359. local   int     File_Parent( File_Name, File_Path, File_Size, File_Info)
  360. /**********************************************************************/
  361. char                    *File_Name, *File_Path;
  362. int                      File_Size;
  363. struct  FileInfoBlock   *File_Info;
  364.  
  365. { extern   struct FileLock *Lock(),     *ParentDir();
  366.   auto     struct FileLock *File_Lock,  *File_Next;
  367.   register int              File_Save,   File_Loop;
  368.  
  369.   if ((File_Lock = Lock( File_Name, SHARED_LOCK)) == NULL) return 0;
  370.   File_Path[File_Loop = File_Size - 1] = NUL;
  371.   do
  372.   { if (!Examine( File_Lock, File_Info))
  373.     { UnLock( File_Lock); return 0; }
  374.  
  375.     File_Save = strlen( File_Info->fib_FileName) + 1;
  376.     if ((File_Loop < File_Save) || (File_Loop < 4))
  377.     { UnLock( File_Lock); return -1; }
  378.     if (File_Save == 1)
  379.          strcpy( &File_Path[File_Loop - (File_Save = 4)], "RAM");
  380.     else strcpy( &File_Path[File_Loop - File_Save], File_Info->fib_FileName);
  381.  
  382.     File_Next = ParentDir( File_Lock); UnLock( File_Lock);
  383.     File_Path[File_Loop - 1] = (File_Next == NULL ? ':' : '/');
  384.     File_Lock = File_Next; File_Loop -= File_Save;
  385.   }
  386.   while (File_Lock != NULL);
  387.  
  388.   if (File_Loop != 0) strcpy( File_Path, &File_Path[File_Loop]);
  389.   return (File_Size - File_Loop);
  390. }
  391.  
  392. /**********************************/
  393. /* Specific File Handling Routine */
  394. /**********************************/
  395.  
  396. local   int     File_Insert()
  397. /***************************/
  398.  
  399. { extern   void   *AllocMem();
  400.   extern   char   *ctime();
  401.   register File   *Temp_File;
  402.   auto     char   *Temp_Date;
  403.   auto     time_t  Temp_Time;
  404.  
  405.   Temp_File = AllocMem( (long) sizeof(File), MEMF_PUBLIC);
  406.   if (Temp_File == NULL) { fprintf( stderr, DATA); return TRUE; }
  407.  
  408.   Temp_Time = Print_Info->fib_Date.ds_Days   * 86400
  409.             + Print_Info->fib_Date.ds_Minute * 60
  410.             + Print_Info->fib_Date.ds_Tick   / TICKS_PER_SECOND;
  411.   Temp_Date = ctime( &Temp_Time);
  412.   memcpy( Temp_File->File_Date, &Temp_Date[4], Date_Size);
  413.  
  414.   Temp_File->File_Opts = Print_Opts;
  415.   Temp_File->File_Flag = Print_Flag;
  416.   Temp_File->File_Copy = Print_Copy;
  417.   Temp_File->File_Size = Print_Info->fib_Size;
  418.  
  419.   if (Print_List == NULL) Print_List            = Temp_File;
  420.   else                    Print_Last->File_Next = Temp_File;
  421.   Print_Last = Temp_File;
  422.   return FALSE;
  423. }
  424.  
  425. local   void    File_Search( Name)
  426. /********************************/
  427. char    *Name;
  428.  
  429. { extern char            *strchr(), *strrchr();
  430.   extern struct FileLock *Lock();
  431.   auto   struct FileLock *File_Lock;
  432.   auto   int              File_Size;
  433.   auto   char            *File_Name, *File_Char;
  434.   auto   char             File_Path[Name_Size];
  435.  
  436.   if ((strchr( Name, '*') == NULL) && (strchr( Name, '?') == NULL))
  437.   { /* Take care of simple file name */
  438.     File_Size = File_Parent( Name, File_Path, Name_Size, Print_Info);
  439.     if (File_Size <= 0)
  440.     { if (File_Size == 0) fprintf( stderr, LOCK, Name);
  441.       else                fprintf( stderr, SIZE, Name, "");
  442.       return;
  443.     }
  444.     File_Path[File_Size - 2] = NUL;
  445.     if ((File_Lock = Lock( File_Path, SHARED_LOCK)) == NULL)
  446.     { fprintf( stderr, LOCK, Name); return; }
  447.  
  448.     if (!Examine( File_Lock, Print_Info))
  449.       fprintf( stderr, LOCK, Name);
  450.     else if (Print_Info->fib_DirEntryType >= 0)
  451.       fprintf( stderr, TYPE, Print_Info->fib_FileName);
  452.     else if (!File_Insert())
  453.       strcpy( Print_Last->File_Name, File_Path);
  454.   }
  455.   else
  456.   { /* Extract the directory part */
  457.     if (((File_Name = strrchr( Name, '/')) == NULL) &&
  458.         ((File_Name = strchr(  Name, ':')) == NULL) )
  459.          File_Name = Name;
  460.     else memcpy( File_Path, Name, ++File_Name - Name);
  461.     File_Path[File_Name - Name] = NUL;
  462.  
  463.     /* Initialize the search */
  464.     File_Size = File_Parent( File_Path, File_Path, Name_Size, Print_Info);
  465.     if (File_Size <= 0)
  466.     { if (File_Size == 0) fprintf( stderr, LOCK, Name);
  467.       else                fprintf( stderr, SIZE, Name, "");
  468.       return;
  469.     }
  470.     if ((File_Lock = Lock( File_Path, SHARED_LOCK)) == NULL)
  471.     { fprintf( stderr, LOCK, File_Path); return; }
  472.  
  473.     if (!Examine( File_Lock, Print_Info))
  474.       fprintf( stderr, LOCK, File_Path);
  475.     else if (Print_Info->fib_DirEntryType < 0)
  476.       fprintf( stderr, TYPE, Print_Info->fib_FileName);
  477.     else
  478.     { /* Search for the matching files */
  479.       while (ExNext( File_Lock, Print_Info))
  480.       { if ((Print_Info->fib_DirEntryType < 0)               &&
  481.             File_Match( Print_Info->fib_FileName, File_Name) )
  482.         { if (File_Size + strlen( Print_Info->fib_FileName) > Name_Size)
  483.             fprintf( stderr, SIZE, File_Path, Print_Info->fib_FileName);
  484.           else if (!File_Insert())
  485.           { strcpy( Print_Last->File_Name, File_Path);
  486.             strcpy( &Print_Last->File_Name[File_Size - 1],
  487.                     Print_Info->fib_FileName);
  488.   } } } } }
  489.   UnLock( File_Lock);
  490. }
  491.  
  492. /************************/
  493. /* Execute the Commands */
  494. /************************/
  495.  
  496. local   void    Exec_Action( Exec)
  497. /********************************/
  498. char    Exec[];
  499.  
  500. { extern int atoi();
  501.   auto   int Code;
  502.  
  503.   if (isdigit( *Exec)) Print_Copy = atoi( Exec);
  504.   else switch( Code = Find_Command( Exec))
  505.   { /* Take care of the options */
  506.     case PS_CPI10   : Options( Line_Density, Line_10);          break;
  507.     case PS_CPI12   : Options( Line_Density, Line_12);          break;
  508.     case PS_CPI17   : Options( Line_Density, Line_17);          break;
  509.     case PS_LPI6    : Options( Page_Density, Page_6);           break;
  510.     case PS_LPI8    : Options( Page_Density, Page_8);           break;
  511.     case PS_NARROW  : Options( Line_Formats, Line_8);           break;
  512.     case PS_WIDE    : Options( Line_Formats, Line_13);          break;
  513.     case PS_SHORT   : Options( Page_Formats, Page_85);          break;
  514.     case PS_LONG    : Options( Page_Formats, Page_11);          break;
  515.     case PS_HEADER  : Print_Opts ^=  Opts_Headers;              break;
  516.     case PS_NUMBER  : Print_Opts ^=  Opts_Numbers;              break;
  517.     case PS_KEEP    : Print_Flag &= ~Flag_Deleted;              break;
  518.     case PS_DELETE  : Print_Flag |=  Flag_Deleted;              break;
  519.     case PS_DRAFT   : Print_Flag &= ~Flag_Quality;              break;
  520.     case PS_LETTER  : Print_Flag |=  Flag_Quality;              break;
  521.  
  522.     /* Take care of the actions */
  523.     case PS_Insert  : case PS_Update  : case PS_Remove :
  524.       if (Print_File != Code) Perform();
  525.       Print_File = Code;                                        break;
  526.  
  527.     case PS_Report  : Perform(); Request_Report();              break;
  528.  
  529.     case PS_Return  : case PS_Change  : case PS_Freeze :
  530.     case PS_Finish  : case PS_Resets  : case PS_Cancel :
  531.     case PS_Resume  : Perform(); Request_Action( Code);         break;
  532.  
  533.     /* Take care of unknown commands */
  534.     default         : fprintf( stderr, EXEC, Exec);             break;
  535. } }
  536.  
  537. /*****************************/
  538. /* This is the Print program */
  539. /*****************************/
  540.  
  541. public  void    main( argc, argv)
  542. /*******************************/
  543. int      argc;
  544. char    *argv[];
  545.  
  546. { extern struct MsgPort *CreatePort();
  547.   extern void           *AllocMem();
  548.  
  549.   printf( "Print  V1.0  27-Mar-88  ) Frangois Gagnon\n");
  550.  
  551.   /* Allocate Initial Structure */
  552.   Print_Port = CreatePort( NULL, 0L);
  553.   if (Print_Port == NULL) { fprintf( stderr, PORT); exit(1); }
  554.   Print_Data = AllocMem( (long) sizeof(struct Inform), MEMF_PUBLIC);
  555.   if (Print_Data == NULL) { fprintf( stderr, DATA); goto Abort1; }
  556.   Print_Info = AllocMem( (long) sizeof(struct FileInfoBlock), MEMF_PUBLIC);
  557.   if (Print_Info == NULL) { fprintf( stderr, DATA); goto Abort2; }
  558.   Default_Values();
  559.  
  560.   /* Analyze the given arguments */
  561.   if (argc == 1) Request_Report();
  562.   else
  563.   { while (++argv, --argc)
  564.     { if      ((*argv)[0] ==       '-') Exec_Action( &(*argv)[1]);
  565.       else if (Print_File == PS_Remove) Request_Remove( *argv);
  566.       else                              File_Search( *argv);
  567.     }
  568.     if (Print_List != NULL) Perform();
  569.   }
  570.  
  571.   /* Deallocate Initial Structure */
  572.   Abort3: FreeMem( Print_Info, (long) sizeof(struct FileInfoBlock));
  573.   Abort2: FreeMem( Print_Data, (long) sizeof(struct Inform));
  574.   Abort1: DeletePort( Print_Port);
  575. }
  576.